package com.ks.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.vo.IngredientVo;
import com.atguigu.vo.MenuSearchVo;
import com.atguigu.vo.SearchVo;
import com.ks.search.config.ESConfig;
import com.atguigu.vo.MenuVo;
import com.ks.search.service.SearchService;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Service
public class SearchServiceImpl implements SearchService {

    @Autowired
    RestHighLevelClient client;

    //向ES数据库种添加数据
    @Override
    public void addMenu(MenuSearchVo menuSearchVo) {
        IndexRequest indexRequest = new IndexRequest("menu_index");
        indexRequest.id(menuSearchVo.getMenuId());
        MenuVo menuVo = new MenuVo();
        BeanUtils.copyProperties(menuSearchVo,menuVo);
        List<IngredientVo> ingredientVos = menuSearchVo.getIngredients();
        StringBuilder ingredientList = new StringBuilder();
        for (IngredientVo ingredientVo : ingredientVos) {
            ingredientList.append(ingredientVo.getIngredientName()).append(" ");
        }
        menuVo.setIngredientList(ingredientList.toString());
        String s = JSON.toJSONString(menuVo);

        indexRequest.source(s, XContentType.JSON);
        indexRequest.timeout(TimeValue.timeValueSeconds(1));
        indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
        indexRequest.create(false);
        try {
            client.index(indexRequest,RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //将传来的食材实体类几个转化为食材字符串
    public String getStr(SearchVo searchVo){
        List<IngredientVo> ingredients = searchVo.getIngredients();
        if (ingredients==null|| ingredients.isEmpty()){
            return null;
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (IngredientVo ingredient : ingredients) {
            stringBuilder.append(ingredient.getIngredientName()).append(" ");
        }
        return stringBuilder.toString();
    }

    //通过传来的口味以及食材来匹配菜谱
    @Override
    public List<MenuVo> getMenus(SearchVo searchVo) {
        List<MenuVo> result = new ArrayList<>();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        String ingredientStr = getStr(searchVo);
        //构建DSL语句
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        boolQueryBuilder.should(QueryBuilders.matchQuery("flavor",searchVo.getFlavor()));
        boolQueryBuilder.should(QueryBuilders.matchQuery("ingredientList",ingredientStr));

        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.from(0);
        sourceBuilder.size(20);
        //发送请求
        SearchRequest searchRequest = new SearchRequest(new String[]{"menu_index"},sourceBuilder);
        try {
            SearchResponse response = client.search(searchRequest, ESConfig.COMMON_OPTIONS);
            result = getResult(response);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    //构建返回结果
    private List<MenuVo> getResult(SearchResponse response) {
        List<MenuVo> result = new ArrayList<>();
        SearchHits hits = response.getHits();
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit searchHit : searchHits) {
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            MenuVo menuVo = new MenuVo();
            menuVo.setMenuId((String) sourceAsMap.get("menuId"));
            menuVo.setMenuName((String)sourceAsMap.get("menuName"));
            menuVo.setMenuStep((String)sourceAsMap.get("menuStep"));
            menuVo.setMenuImg((String)sourceAsMap.get("menuImg"));
            menuVo.setFlavor((String)sourceAsMap.get("flavor"));
            menuVo.setUserId((String)sourceAsMap.get("userId"));
            menuVo.setCostTime((Integer)sourceAsMap.get("costTime"));
            menuVo.setCollectedNumber((Integer)sourceAsMap.get("collectedNumber"));
            menuVo.setLikedNumber((Integer)sourceAsMap.get("likedNumber"));
            menuVo.setIngredientList((String)sourceAsMap.get("ingredientList"));
            result.add(menuVo);
        }
        return result;
    }
}
